package com.apache.funds.common;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.apache.api.vo.ParamsVo;
import com.apache.database.constant.SpringContextLoader;
import com.apache.database.constant.SystemTools;
import com.apache.database.constant.Validator;
import com.apache.funds.manager.SvmCaptionBalanceManager;
import com.apache.funds.util.Constants;
import com.apache.funds.vo.UserFundsVo;
import com.apache.tools.StrUtil;

/**
 * 缓存操作类
 * @author xhe
 *
 */
public class FundsCache {
	private Logger log = LoggerFactory.getLogger(getClass());
	private SvmCaptionBalanceManager svmCaptionBalanceManager;

	private static FundsCache instance;

	private FundsCache() {
		svmCaptionBalanceManager = (SvmCaptionBalanceManager) SpringContextLoader.getBean("svmCaptionBalanceManager");
	}

	public static synchronized FundsCache getInstance() {
		if (null == instance)
			instance = new FundsCache();
		return instance;
	}

	/**
	 * 初始化余额缓存
	 * @param userEname
	 */
	@SuppressWarnings("rawtypes")
	public void initBalanCache(String userEname) {
		ParamsVo vo = new ParamsVo();
		vo.setParams("userId", userEname);
		UserFundsVo uFundsVo = getUserFundsVo(vo);
		if (uFundsVo != null) {
			boolean b = SystemTools.getInstance().getCache("").createCacheObject(userEname, uFundsVo);
			log.info("用户[" + userEname + "]余额查询完毕，添加缓存完成" + b);
		} else {
			log.info("用户[" + userEname + "]余额查询完毕， UserFundsVo is null ，所以不向缓存中添加");
		}
	}

	public UserFundsVo getBalanCache(String userEname) {
		UserFundsVo fundsVo = new UserFundsVo();
		Object cacheObj = SystemTools.getInstance().getCache("").getCacheCloneByKey(userEname.trim());
		if (cacheObj == null) {
			//再次加载
			initBalanCache(userEname.trim());
			cacheObj = SystemTools.getInstance().getCache("").getCacheCloneByKey(userEname.trim());
		}
		fundsVo = (UserFundsVo) cacheObj;
		//		log.info("从缓存读取用户["+userEname.trim()+"]余额："+fundsVo);
		return fundsVo;
	}

	/**
	 * 直接更新设置（谨慎使用）
	 * @param userEname
	 * @param userFundsVo
	 */
	public void updateBalanCache(String userEname, UserFundsVo userFundsVo) {
		SystemTools.getInstance().getCache("").createCacheObject(userEname, userFundsVo);
	}

	/**
	 * 【余额最核心算法】（每日操作过程中都会以此为准）
	 * 根据情况进行更新对应人缓存（根据业务情况，推荐使用）
	 * @param userEname 谁(账号）
	 * @param cap 那个科目（m1,m2,m3,m4,m5,m6）
	 * @param descr 进行（in，out）
	 * @param amt 多少金额
	 */
	public void updateBalanCache(String userEname, String cap, String descr, long amt) {
		if (StrUtil.isNull(userEname) && StrUtil.isNull(cap) && StrUtil.isNull(descr) && amt > 0) {
			log.info("刷新[" + userEname + "]余额缓存时参数不能为空！");
		}
		UserFundsVo fundVo = getBalanCache(userEname);
		if (fundVo != null) {
			if ("m1".equals(cap)) {
				if (Constants.Description.IN.equals(descr)) {
					fundVo.setM1(NumberUtil.add(fundVo.getM1(), amt));//加法
				} else if (Constants.Description.OUT.equals(descr)) {
					fundVo.setM1(NumberUtil.sub(fundVo.getM1(), amt));//减法
				}
			} else if ("m2".equals(cap)) {
				if (Constants.Description.IN.equals(descr)) {
					fundVo.setM2(NumberUtil.add(fundVo.getM2(), amt));//加法
				} else if (Constants.Description.OUT.equals(descr)) {
					fundVo.setM2(NumberUtil.sub(fundVo.getM2(), amt));//减法
				}
			} else if ("m3".equals(cap)) {
				if (Constants.Description.IN.equals(descr)) {
					fundVo.setM3(NumberUtil.add(fundVo.getM3(), amt));//加法
				} else if (Constants.Description.OUT.equals(descr)) {
					fundVo.setM3(NumberUtil.sub(fundVo.getM3(), amt));//减法
				}
			} else if ("m4".equals(cap)) {
				if (Constants.Description.IN.equals(descr)) {
					fundVo.setM4(NumberUtil.add(fundVo.getM4(), amt));//加法
				} else if (Constants.Description.OUT.equals(descr)) {
					fundVo.setM4(NumberUtil.sub(fundVo.getM4(), amt));//减法
				}
			} else if ("m5".equals(cap)) {
				if (Constants.Description.IN.equals(descr)) {
					fundVo.setM5(NumberUtil.add(fundVo.getM5(), amt));//加法
				} else if (Constants.Description.OUT.equals(descr)) {
					fundVo.setM5(NumberUtil.sub(fundVo.getM5(), amt));//减法
				}
			} else if ("m6".equals(cap)) {
				if (Constants.Description.IN.equals(descr)) {
					fundVo.setM6(NumberUtil.add(fundVo.getM6(), amt));//加法
				} else if (Constants.Description.OUT.equals(descr)) {
					fundVo.setM6(NumberUtil.sub(fundVo.getM6(), amt));//减法
				}
			}
			updateBalanCache(userEname, fundVo);
			log.info("[" + userEname + "]账户余额缓存刷新完成！");
		}
	}

	/**
	 * 访问数据库查询我的余额
	 * @param vo
	 * @return
	 */
	private UserFundsVo getUserFundsVo(ParamsVo vo) {
		UserFundsVo userFundsVo = null;

		String userId = String.valueOf(vo.getParams("userId"));
		if (Validator.isNull(userId)) {
			log.info("userId[" + userId + "]不能为空！，返回空userFundsVo");
			return userFundsVo;
		}

		List<UserFundsVo> list = (List<UserFundsVo>) svmCaptionBalanceManager.execute(vo);
		if (list == null || list.isEmpty()) {
			log.error("未查询到账户[" + userId + "]昨日余额统计对象，可能是昨日余额结存（期初+发生）定时器未执行！###@@@@@#### ！");
			return userFundsVo;
		}
		userFundsVo = list.get(0);

		//		在实体get方法计算了
		//		userFundsVo.setBalanTotal(NumberUtil.doubleToLong(NumberUtil.add(userFundsVo.getM1(), userFundsVo.getM2(), 2)));//总金额=m1+m2;

		return userFundsVo;
	}

	public void setSvmCaptionBalanceManager(SvmCaptionBalanceManager svmCaptionBalanceManager) {
		this.svmCaptionBalanceManager = svmCaptionBalanceManager;
	}

	public static void main(String[] args) {
		UserFundsVo vo = new UserFundsVo();
		vo.setM1(12121212121200l);
		vo.setM2(200l);
		double a = NumberUtil.add(vo.getM1(), vo.getM2(), 2);
		System.out.println(NumberUtil.doubleToLong(a));
	}

}
